﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Infrastructure;

namespace HA.MT3DMS.DomainLayer
{
    [Serializable]
   public class  MTGrid
    {

        public MTGrid(int nrow,int ncol,int nlayer)
        {

            this._nrows = nrow;
            this._ncols = ncol;
            this._nlayers = nlayer;


            this._layers = new List<MTGridLayer>();



            this.OnResetGrid();


        


 
        }


        #region 事件模型

        [field:NonSerialized]
        public event EventHandler GridReseted;
        #endregion


        int _nrows;

        public int Nrows
        {
            get { return _nrows; }
            set { _nrows = value; }
        }

        int _ncols;

        public int Ncols
        {
            get { return _ncols; }
            set { _ncols = value; }
        }

        int _nlayers;

        public int Nlayers
        {
            get { return _nlayers; }
            set { _nlayers = value; }
        }


        List<MTGridLayer> _layers;

        public List<MTGridLayer> Layers
        {
            get { return _layers; }
           
        }


        List<double[,]> _elevations=new List<double[,]> ();

        public List<double[,]> Elevations
        {
            get { return _elevations; }
            
          
        }


        double[] _rowCoords;

        /// <summary>
        /// 
        /// </summary>
        public double[] RowCoords
        {
            get { return _rowCoords; }

        }

        double[] _colCoords;

        public double[] ColCoords
        {
            get { return _colCoords; }

        }
     





        #region 受保护的函数

        protected void OnResetGrid()
        {

            this._layers.Clear();


            for (int i = 0; i < this._nlayers; i++)
            {
                MTGridLayer layer = new MTGridLayer(this._nrows,this._ncols);

                this._layers.Add(layer);

                
            }
 
        }

        #endregion


        #region 公共函数


        public double[] GetDelR()
        {
            double[] delr = new double[this._ncols];

            for (int i = 0; i < this.ColCoords.Length - 1; i++)
            {
                delr[i] = this.ColCoords[i + 1] - this.ColCoords[i];

            }

            return delr;


        }

        public double[] GetDelC()
        {
            double[] delc = new double[this._nrows];

            for (int j = 0; j < this.RowCoords.Length - 1; j++)
            {
                delc[j] = this.RowCoords[j + 1] - this.RowCoords[j];
            }

            return delc;

        }

        /// <summary>
        /// 暂时只返回第一层顶部高程值，有待最终确定
        /// </summary>
        public double[,] GetTopH()
        {
            double[,] topH = this._elevations[0];


            //HA.ModFlow.Infrastructure.CellCenterDataSet3d ds = new CellCenterDataSet3d(this.Elevations, this.GetICBUND(), this.Nrows, this.Ncols, this.Nlayers);
            

            return topH;
        }

        public void SetTopH(List<double[,]> topH)
        {
            //移除除最后一层的底部高程以外的所有高程值
            this._elevations.RemoveRange(0,this._elevations.Count-1);
            int i = 0;
            foreach (double[,] item in topH)
            {
                this._elevations.Insert(i,(double[,])item.Clone());
                i++;
            }
        }

        public void SetElevations(List<double[,]> elevations)
        {
            this._elevations.Clear();
            
            this._elevations.AddRange(elevations);


            //更新dz值

            int n = 0;

            foreach (MTGridLayer layer in this._layers)
            {

                for (int i = 0; i < this._nrows; i++)
                {

                    for (int j = 0; j < this._ncols; j++)
                    {
                        layer.DZ[i, j] = this._elevations[n][i, j] - this._elevations[n + 1][i, j];
                        
                    }

                }
               


                n++;

            }




        }

        public void SetICBUND(List<int[,]> icbund)
        {
            int i = 0;
            foreach (MTGridLayer layer in this.Layers)
            {
                layer.Icbund = (int[,])icbund[i].Clone();
                i++;
            }
        }


        /// <summary>
        /// 返回icbund的副本
        /// </summary>
        public List<int[,]> GetICBUND()
        {

            List<int[,]> icbund = new List<int[,]>();

            foreach (MTGridLayer item in this.Layers)
            {
               icbund.Add((int[,])item.Icbund.Clone());
            }

            return icbund;

        }

        public CellCenterDataSet3d GetICBoundDS()
        {
            int nrow = this.Nrows;
            int ncol = this.Ncols;

            int nlayer = this.Nlayers;

            List<int[,]> ibound = this.GetICBUND();



            double[, ,] dbound = new double[nrow, ncol, nlayer];

            for (int k = 0; k < nlayer; k++)
            {
                for (int i = 0; i < nrow; i++)
                {
                    for (int j = 0; j < ncol; j++)
                    {




                        dbound[i, j, k] = (double)ibound[k][i, j];



                    }
                }

            }



            CellCenterDataSet3d dsBound = new CellCenterDataSet3d(dbound, ibound);
            dsBound.Label = "ICBUND边界";


            return dsBound;
        }

        public void SetICBoundDS(CellCenterDataSet3d ds)
        {

            List<double[,]> temp = new List<double[,]>();
            if (ds.GetAllGridData(temp))
            {
                List<int[,]> lisTemp = new List<int[,]>();
                for (int k = 0; k < temp.Count; k++)
                {
                    int[,] ibound = new int[temp[k].GetLength(0), temp[k].GetLength(1)];
                    for (int i = 0; i < temp[k].GetLength(0); i++)
                    {
                        for (int j = 0; j < temp[k].GetLength(1); j++)
                        {
                            ibound[i, j] = (int)temp[k][i, j];
                        }
                    }
                    lisTemp.Add(ibound);
                }


                this.SetICBUND(lisTemp);
               
            }






        }


        public List<double[,]> GetPorosity()
        {
            List<double[,]> porosity = new List<double[,]>();

            foreach (MTGridLayer layer in this.Layers)
            {
                porosity.Add(layer.Porosity);
            }


            return porosity;
 
        }

        public void SetPorosity(List<double[,]> porosity)
        {
            int i = 0;
            foreach (MTGridLayer layer in this.Layers)
            {
                layer.Porosity = (double[,])porosity[i].Clone();
                i++;
            }
        }

        public void ResetGrid(int nrow, int ncol, int nlayer,double[] rowCoord,double[] colCoord)
        {
            this._nrows = nrow;
            this._ncols = ncol;
            this._nlayers = nlayer;

            this._rowCoords = rowCoord;
            this._colCoords = colCoord;




            this.OnResetGrid();

            if (this.GridReseted!=null)
            {
                GridReseted(this,new EventArgs ());
                
            }




 
        }

        #endregion

    }
}
